package com.snopy.socket;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Semaphore;

/**
 * @author snopy
 * @version 1.0.0
 * @classname KnockKnockServer
 * @description
 * @email 77912204@qq.com
 * @date 2022/08/01 16:00
 */
@Slf4j
public class KnockKnockServer {
    public static final Semaphore semaphore = new Semaphore(5);

    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java KnockKnockServer <port number>");
            System.exit(1);
        }
        int portNumber = Integer.parseInt(args[0]);
        try(
                ServerSocket serverSocket = new ServerSocket(portNumber);
        ) {
                while (true) {
                    semaphore.acquire();
                    new Thread(() -> {
                        try {

                            Socket socket = serverSocket.accept();
                            PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

                            BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                            String inputLine, outputLine;
                            KnockKnockProtocol kkp = new KnockKnockProtocol();
                            outputLine = kkp.processInput(null);
                            out.println(outputLine);
                            while ((inputLine = in.readLine()) != null) {
                                outputLine = kkp.processInput(inputLine);
                                out.println(outputLine);
                                if (outputLine.equals("Bye.")) {
                                    break;
                                }
                            }
                            serverSocket.close();
                            semaphore.release();
                        } catch (IOException e) {
                            log.error("Exception caught when trying to listen on port:{} or listening for a connection", portNumber);
                            log.error(e.getMessage());
                        }

                    }).start();
                }

        } catch (IOException e) {
            log.error("Exception caught when trying to listen on port:{} or listening for a connection",portNumber);
            log.error(e.getMessage());
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}
